package com.example.controller;

import com.example.service.RedisService;
import com.example.service.SomeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/redis/test")
public class RedisTestController {

    private static final Logger logger = LoggerFactory.getLogger(RedisTestController.class);

    private final RedisService redisService;
    private final SomeService someService;

    @Autowired
    public RedisTestController(RedisService redisService, SomeService someService) {
        this.redisService = redisService;
        this.someService = someService;
    }

    @GetMapping("/test")
    public String testRedisConnection() {
        logger.info("开始 Redis 测试操作");

        someService.someMethod();
        redisService.setValue("Hello Redis!");

        String value = redisService.getValue();
        logger.info("从 Redis 中获取的值: {}", value);

        return value;
    }

    // ================ 队列操作（List） ==================
    @PostMapping("/queue")
    public void addToQueue(@RequestParam String value) {
        logger.info("添加值到队列: {}", value);
        redisService.addToQueue(value);
    }

    @GetMapping("/queue")
    public String popFromQueue() {
        String value = redisService.popFromQueue();
        logger.info("从队列中弹出的值: {}", value);
        return value;
    }

    // ================ 排行榜操作（Sorted Set） ==================
    @PostMapping("/leaderboard")
    public void addToLeaderboard(@RequestParam String player, @RequestParam double score) {
        logger.info("添加玩家到排行榜: {}, 分数: {}", player, score);
        redisService.addToLeaderboard(player, score);
    }

    @GetMapping("/leaderboard/top")
    public Set<String> getTopLeaderboard() {
        Set<String> topPlayers = redisService.getTopFromLeaderboard(10);
        logger.info("排行榜前10名玩家: {}", topPlayers);
        return topPlayers;
    }

    // ================ 在线用户操作（Set） ==================
    @PostMapping("/online/users")
    public void addOnlineUser(@RequestParam String userId) {
        logger.info("用户上线: {}", userId);
        redisService.addOnlineUser(userId, 5, TimeUnit.MINUTES);
    }

    @GetMapping("/online/users/count")
    public Long getOnlineUserCount() {
        Long onlineCount = redisService.getOnlineUsersCount();
        logger.info("当前在线用户数: {}", onlineCount);
        return onlineCount;
    }

    // ================ 用户位置操作（Geo） ==================
    @PostMapping("/user/location")
    public void saveUserLocation(@RequestParam String user, @RequestParam double latitude, @RequestParam double longitude) {
        logger.info("保存用户 {} 的位置: 纬度 {}, 经度 {}", user, latitude, longitude);
        redisService.saveUserLocation(user, latitude, longitude);
    }

    @GetMapping("/user/distance")
    public Double getUserDistance(@RequestParam String user1, @RequestParam String user2) {
        Double distance = redisService.getUserDistance(user1, user2);
        logger.info("用户 {} 和 用户 {} 之间的距离: {} 米", user1, user2, distance);
        return distance;
    }

    // ================ 哈希操作（Hash） ==================
    @PostMapping("/hash")
    public void setHashValue(@RequestParam String key, @RequestParam String value) {
        logger.info("设置哈希键值对: key={}, value={}", key, value);
        redisService.setHashValue(key, value);
    }

    @GetMapping("/hash")
    public Object getHashValue(@RequestParam String key) {
        Object value = redisService.getHashValue(key);
        logger.info("获取哈希键: {}, 值: {}", key, value);
        return value;
    }

    @GetMapping("/hash/all")
    public Map<Object, Object> getAllHashValues() {
        Map<Object, Object> entries = redisService.getAllHashValues();
        logger.info("获取哈希中的所有键值对: {}", entries);
        return entries;
    }

    @DeleteMapping("/hash")
    public void deleteHashKey(@RequestParam String key) {
        logger.info("删除哈希中的键: {}", key);
        redisService.deleteHashKey(key);
    }

    // ================ HyperLogLog 操作 ==================
    @PostMapping("/hyperloglog")
    public void addToHyperLogLog(@RequestParam String value) {
        logger.info("向 HyperLogLog 中添加值: {}", value);
        redisService.addToHyperLogLog(value);
    }

    @GetMapping("/hyperloglog/count")
    public Long getHyperLogLogCount() {
        Long count = redisService.getHyperLogLogCount();
        logger.info("获取 HyperLogLog 的基数统计: {}", count);
        return count;
    }

    // ================ Bitmap 操作 ==================
    @PostMapping("/bitmap/set")
    public void setBit(@RequestParam long offset, @RequestParam boolean value) {
        logger.info("设置 Bitmap 中的位 {} 为: {}", offset, value);
        redisService.setBit(offset, value);
    }

    @GetMapping("/bitmap/get")
    public Boolean getBit(@RequestParam long offset) {
        Boolean bitValue = redisService.getBit(offset);
        logger.info("获取 Bitmap 中的位 {} 的值: {}", offset, bitValue);
        return bitValue;
    }

    // ================ Stream 操作 ==================
    @PostMapping("/stream")
    public String addToStream(@RequestParam String field, @RequestParam String value) {
        logger.info("向 Stream 中添加数据: {} -> {}", field, value);
        return redisService.addToStream(field, value);
    }

    @GetMapping("/stream")
    public List<MapRecord<String, Object, Object>> readFromStream(@RequestParam String startId, @RequestParam String endId) {
        logger.info("读取 Stream 中的记录, 从ID: {} 到ID: {}", startId, endId);
        return redisService.readFromStream(startId, endId);
    }

    // ================ 排行榜操作 ==================
    @PostMapping("/leaderboard/update")
    public Long updateLeaderboard(@RequestParam String uid, @RequestParam double score) {
        logger.info("收到更新请求 - 玩家: {}, 累加分数: {}", uid, score);
        return redisService.updateLeaderboardScore(uid, score, true);
    }
}
